/*
 * Created by SharpDevelop.
 * User: Steve
 * Date: 26/10/2006
 * Time: 11:20 PM
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Mokey.ThunderCards.Settings;
using System.Text.RegularExpressions;
using Mokey.ThunderCards.Cards;
using Mokey.Common.Forms;
using System.IO;

namespace Mokey.ThunderCards
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm
	{
        private const string SETTINGS_FILE_NAME = "mtc_settings.xml";

        private SettingsFile _settings;
        private FormFader _popUpFader;
        private Timer _cardDurationTimer;
        private Timer _cardFrequencyTimer;
        private bool _cardsEnabled = false;
        private PopUpForm _cardDisplayForm;
        private int _currentCardIndex = 0;

		[STAThread]
		public static void Main(string[] args)
		{
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);
			Application.Run(new MainForm());
		}
		
		public MainForm()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();

            _cardDurationTimer = new Timer();
            _cardFrequencyTimer = new Timer();

            PlaySoundDropDown.DataSource = Enum.GetValues(typeof(SoundStatusEnum));
            LoadSettings();
            _cardDisplayForm = new PopUpForm();
            _cardDisplayForm.UserInteracted += new EventHandler(_cardDisplayForm_UserInteracted);
            _cardDisplayForm.UserFinishedInteraction += new EventHandler(_cardDisplayForm_UserFinishedInteraction);
            
            _popUpFader = new FormFader(_cardDisplayForm, 1);
            _popUpFader.FadingFinished += new EventHandler(_popUpFader_FadingFinished);

            _cardDurationTimer.Tick += new EventHandler(_cardDurationTimer_Tick);
            _cardFrequencyTimer.Tick += new EventHandler(_cardFrequencyTimer_Tick);

            if (_settings.AutoStartCardShow)
            {
                StartCardShow();
            }
		}

        private void LoadSettings()
        {
            _settings = new SettingsFile(string.Format("{0}\\{1}", Application.StartupPath, SETTINGS_FILE_NAME));
            PopUpFrequencyTextBox.Text = _settings.PopUpFrequency.ToString();
            PopUpDurationTextBox.Text = _settings.PopUpDisplayTime.ToString();
            WindowHeightTextBox.Text = _settings.PopUpHeight.ToString();
            WindowWidthTextBox.Text = _settings.PopUpWidth.ToString();
            PlaySoundDropDown.SelectedItem = _settings.SoundStatus;
            HideQuestionsCheckbox.Checked = !_settings.AutoShowQuestions;
            HideAnswersCheckbox.Checked = !_settings.AutoShowAnswers;
            AutoStartCardShowCheckbox.Checked = _settings.AutoStartCardShow;

            _cardDurationTimer.Interval = _settings.PopUpDisplayTime * 1000;
            _cardFrequencyTimer.Interval = _settings.PopUpFrequency * 1000;

            if (!string.IsNullOrEmpty(_settings.LastOpenedCardPack))
            {
                if (!LoadCardList(_settings.LastOpenedCardPack))
                {
                    UIHelper.DisplayErrorMessage("Could not find last opened card pack:\n" + _settings.LastOpenedCardPack);
                    _settings.LastOpenedCardPack = string.Empty;
                    _settings.Save();
                }
            }
        }

        private void SaveSettings()
        {
            if (PopUpFrequencyTextBox.Text != string.Empty)
                _settings.PopUpFrequency = int.Parse(PopUpFrequencyTextBox.Text);
            if (PopUpDurationTextBox.Text != string.Empty)
                _settings.PopUpDisplayTime = int.Parse(PopUpDurationTextBox.Text);
            if (WindowHeightTextBox.Text != string.Empty)
                _settings.PopUpHeight = int.Parse(WindowHeightTextBox.Text);
            if (WindowWidthTextBox.Text != string.Empty)
                _settings.PopUpWidth = int.Parse(WindowWidthTextBox.Text);
            _settings.SoundStatus = (SoundStatusEnum)PlaySoundDropDown.SelectedValue;
            _settings.AutoShowQuestions = !HideQuestionsCheckbox.Checked;
            _settings.AutoShowAnswers = !HideAnswersCheckbox.Checked;
            _settings.AutoStartCardShow = AutoStartCardShowCheckbox.Checked;
            _settings.Save();

            _cardDurationTimer.Interval = _settings.PopUpDisplayTime * 1000;
            _cardFrequencyTimer.Interval = _settings.PopUpFrequency * 1000;
        }

		private void ShowOptions()
		{
            this.WindowState = FormWindowState.Normal;
			this.ShowInTaskbar = true;
			this.Focus();
		}
		
		private void HideOptions()
        {
            SaveSettings();
            this.WindowState = FormWindowState.Minimized;
            this.ShowInTaskbar = false;
        }

        private void StartCardShow()
        {
            // toggle the timer and change the text of the toggle button to describe whether it will pause or start next
            _cardsEnabled = !_cardsEnabled;
            _cardFrequencyTimer.Enabled = _cardsEnabled;
            //always set this to false on the start/pause - it's starting state is disabled and we disable it to stop
            _cardDurationTimer.Enabled = false;
            //shut down the open popups
            _popUpFader.FadeOut();
            StartPauseToolStripMenuItem.Text = _cardsEnabled ? "Pause" : "Start";
        }

        #region Tool Strip Event Handlers

        void ExitToolStripMenuItemClick(object sender, System.EventArgs e)
		{
			Application.Exit();
		}
		
		void OptionsToolStripMenuItemClick(object sender, System.EventArgs e)
		{
			ShowOptions();
		}
		
		void StatusBarNotifyIconDoubleClick(object sender, System.EventArgs e)
		{
			ShowOptions();
        }

        private void StartPauseToolStripMenuItem_Click(object sender, EventArgs e)
        {
            StartCardShow();
        }

        private void LoadCardsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenCardPack();
        }

        #endregion

        #region Form Event Handlers

        private void _cardDisplayForm_UserFinishedInteraction(object sender, EventArgs e)
        {
            _cardDurationTimer.Enabled = true;
        }

        private void _cardDisplayForm_UserInteracted(object sender, EventArgs e)
        {
            _popUpFader.CancelFade();
            _cardDisplayForm.Opacity = 1;
            _cardDurationTimer.Enabled = false;
            _cardFrequencyTimer.Enabled = false;
        }

        private void _popUpFader_FadingFinished(object sender, EventArgs e)
        {
            if (_cardDisplayForm.Opacity == 0)
            {
                _cardDisplayForm.Hide();
                _cardFrequencyTimer.Enabled = true;
            }
        }

        private void CloseButton_Click(object sender, EventArgs e)
        {
            HideOptions();
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
            HideOptions();
        }

        #endregion

        #region Options Event Handlers

        private void NumericalTextBox_TextChanged(object sender, EventArgs e)
        {
            TextBox numericalTextBox = (TextBox)sender;
            int cursorPosition = numericalTextBox.SelectionStart;
            numericalTextBox.Text = Regex.Replace(numericalTextBox.Text, "[^0-9]", string.Empty);
            if (cursorPosition <= numericalTextBox.Text.Length)
            {
                numericalTextBox.SelectionStart = cursorPosition;
            }
            else
            {
                numericalTextBox.SelectionStart = numericalTextBox.Text.Length;
            }
            numericalTextBox.SelectionLength = 0;
        }

        #endregion

        #region Card List Event Handlers

        private void AddCardButton_Click(object sender, EventArgs e)
        {
            using (AddEditCardDialog addCardDialog = new AddEditCardDialog())
            {
                if (addCardDialog.ShowDialog() == DialogResult.OK)
                {
                    _cardList.Cards.Add(addCardDialog.Card);
                    RebindCardList();
                }
            }
        }

        private void EditCardButton_Click(object sender, EventArgs e)
        {
            if (CardListBox.SelectedItem != null)
            {
                using (AddEditCardDialog editCardDialog = new AddEditCardDialog())
                {
                    editCardDialog.Card = (ThunderCard)CardListBox.SelectedItem;
                    if (editCardDialog.ShowDialog() == DialogResult.OK)
                    {
                        RebindCardList();
                    }
                }
            }
            else
            {
                UIHelper.DisplayValidationMessage("Please select a card to edit");
            }
        }

        private void RemoveCardButton_Click(object sender, EventArgs e)
        {
            if (CardListBox.SelectedItem != null)
            {
                _cardList.Cards.Remove((ThunderCard)CardListBox.SelectedItem);
                RebindCardList();
            }
            else
            {
                UIHelper.DisplayValidationMessage("Please select a card to edit");
            }
        }

        private void SavePackButton_Click(object sender, EventArgs e)
        {

            //if we don't have a file name, then we need to show a "save as" dialog
            if (string.IsNullOrEmpty(_cardList.FilePath))
            {
                if (SavePackDialog.ShowDialog() == DialogResult.OK)
                {
                    _cardList.SaveAs(SavePackDialog.FileName);
                }
            }
            else
            {
                _cardList.Save();
            }
        }

        private void LoadPackButton_Click(object sender, EventArgs e)
        {
            OpenCardPack();
        }

        private void SavePackAsButton_Click(object sender, EventArgs e)
        {
            if (SavePackDialog.ShowDialog() == DialogResult.OK)
            {
                _cardList.SaveAs(SavePackDialog.FileName);
            }
        }

        #endregion

        #region Timer Event Handlers

        private void _cardFrequencyTimer_Tick(object sender, EventArgs e)
        {
            if (_cardList.Cards.Count > 0)
            {
                _cardFrequencyTimer.Enabled = false;
                _cardDurationTimer.Enabled = true;

                if (_currentCardIndex >= _cardList.Cards.Count)
                {
                    _currentCardIndex = 0;
                }
                _cardDisplayForm.LoadCard(_cardList.Cards[_currentCardIndex], _settings.SoundStatus, _settings.AutoShowQuestions, 
                    _settings.AutoShowAnswers, _cardList.MediaFolderPath);
                _currentCardIndex++;
                _popUpFader.FadeIn();
                _cardDisplayForm.WindowState = FormWindowState.Normal;
                _cardDisplayForm.SetSizeAndPosition(new Size(_settings.PopUpWidth, _settings.PopUpHeight));
                _cardDisplayForm.Show();
            }
        }

        private void _cardDurationTimer_Tick(object sender, EventArgs e)
        {
            _cardDurationTimer.Enabled = false;
            _popUpFader.FadeOut();
        }

        #endregion

        #region Card List Methods

        private CardListFile _cardList = new CardListFile();
        private bool LoadCardList(string filePath)
        {
            if (File.Exists(filePath))
            {
                try
                {
                    _cardList = new CardListFile(filePath);
                    CardListBox.DataSource = _cardList.Cards;
                    _settings.LastOpenedCardPack = filePath;
                    _settings.Save();
                    return true;
                }
                catch (Exception e)
                {
                    UIHelper.DisplayExceptionMessage(e);
                }
            }
            return false;
        }

        private void RebindCardList()
        {
            CardListBox.DataSource = null;
            CardListBox.DataSource = _cardList.Cards;
        }

        private void OpenCardPack()
        {
            if (LoadPackDialog.ShowDialog() == DialogResult.OK)
            {
                LoadCardList(LoadPackDialog.FileName);
            }
        }

        #endregion
    }
}
